#include "main.h"
#include "ParseEIT.h"
#include "ParseTS_Head.h"
#include "ParseType.h"

void ParseEIT_Section(unsigned char EITtable[1200],TS_EIT *NewEitPoint);
static int eit_i,eit_n,eit_l;
static unsigned int EIT_CRC[4096];
static unsigned char EIT_Long_Table[1200];
static unsigned char CountEIT;

void TSEIT_Table(unsigned char EITtable[1200],TS_EIT *NewEitPoint)
{
    int EIT_Length = 0;

	NewEitPoint->table_id = EITtable[0];
	NewEitPoint->section_syntax_indicator = EITtable[1] >> 7;
	NewEitPoint->reserved_future_use = (EITtable[1] >> 6) & 0x01;
	NewEitPoint->reserved1 = (EITtable[1] >> 4) & 0x03;
	NewEitPoint->section_length = ((EITtable[1] & 0x0F)) << 8 | EITtable[2];
	NewEitPoint->service_id = (EITtable[3] << 8) | EITtable[4];
	NewEitPoint->reserved2 = EITtable[5] >> 6;
	NewEitPoint->version_number = (EITtable[5] >> 1) & 0x1F;
	NewEitPoint->current_next_indicator = (EITtable[5] << 7) >> 7;
	NewEitPoint->section_number = EITtable[6];
	NewEitPoint->last_section_number = EITtable[7];
	NewEitPoint->transport_stream_id = (EITtable[8] << 8) | EITtable[9];
	NewEitPoint->original_network_id = (EITtable[10] << 8) | EITtable[11];
	NewEitPoint->segment_last_section_number = EITtable[12];
	NewEitPoint->last_table_id = EITtable[13];
	
    ParseEIT_Section(EITtable, NewEitPoint);

    EIT_Length = NewEitPoint->section_length + 3;
	NewEitPoint->CRC_32 = (EITtable[EIT_Length - 4] << 24) | (EITtable[EIT_Length - 3] << 16)
	        | (EITtable[EIT_Length - 2] << 8) | EITtable[EIT_Length - 1];


	if(NewEitPoint->section_length > 188)
	{
		eit_l = NewEitPoint->section_length;
	}

	if((NewEitPoint->section_length < 188 && NewEitPoint->CRC_32 != 0) || ((eit_l / 188) == eit_n && NewEitPoint->CRC_32 != 0))
	{
		if(eit_i == 0)
		{
			NewEitPoint->next = NULL;
			NewEitPoint->Previous = EitPoint;
			EitPoint->next = NewEitPoint;
			EitPoint = EitPoint->next;

			EIT_CRC[eit_i] = NewEitPoint->CRC_32;

			eit_i ++;
		}else
		{
			for(int p = 0; p < eit_i; p++)
			{
				if(EIT_CRC[p] == NewEitPoint->CRC_32)
				{
					return;
				}
			}
				NewEitPoint->next = NULL;
				NewEitPoint->Previous = EitPoint;
				EitPoint->next = NewEitPoint;
				EitPoint = EitPoint->next;

				EIT_CRC[eit_i] = NewEitPoint->CRC_32;

				eit_i ++;
		}
	} 
}

void ParseEIT_Section(unsigned char EITtable[1200],TS_EIT *NewEitPoint)
{
	int EIT_Length = 0;
	int EventPosition = 0;
	int EventCount = 0;

	EIT_Length = NewEitPoint->section_length + 3;
	
    for (EventPosition = 14; EventPosition < EIT_Length - 4; EventPosition += 12)
	{
		NewEitPoint->astEIT_Info[EventCount].event_id = (EITtable[EventPosition]) << 8 | EITtable[EventPosition + 1];
		memcpy(NewEitPoint->astEIT_Info[EventCount].start_time, EITtable + EventPosition + 2, 5);
		NewEitPoint->astEIT_Info[EventCount].duration = (EITtable[EventPosition + 7] << 16)
		        | (EITtable[EventPosition + 8] << 8) | (EITtable[EventPosition + 9]);
		NewEitPoint->astEIT_Info[EventCount].running_status = EITtable[EventPosition + 10] >> 5;
		NewEitPoint->astEIT_Info[EventCount].freed_CA_mode = (EITtable[EventPosition + 10] & 0x1F) >> 4;
		NewEitPoint->astEIT_Info[EventCount].descriptors_loop_length = ((EITtable[EventPosition + 10] & 0x0F) << 8)
		        | EITtable[EventPosition + 11];
                
		if (NewEitPoint->astEIT_Info[EventCount].descriptors_loop_length != 0)
		{
			memcpy(NewEitPoint->astEIT_Info[EventCount].descriptor, EITtable + 12 + EventPosition,
			        NewEitPoint->astEIT_Info[EventCount].descriptors_loop_length);
			EventPosition += NewEitPoint->astEIT_Info[EventCount].descriptors_loop_length;
		}

		EventCount++;
	}

}

void ParseTS_EIT_1(int TsPackage_len,TS_Package_Head TS_PackageEITHead)
{
    TS_EIT TS_PackageEIT = {0};
	unsigned char EITtable[204] = {0};
	TS_EIT *NewEitPoint = (TS_EIT *)malloc(sizeof(TS_EIT));
	
	CountEIT = TS_PackageEITHead.continuity_counter;

    memcpy(EITtable, TSdata+5, TsPackage_len-5);

    TSEIT_Table(EITtable, NewEitPoint);

	eit_n = 0;	
	memset(EIT_Long_Table, 0, 1200);
	memcpy(EIT_Long_Table, TSdata+5, TsPackage_len-5);

}

void ParseTS_EIT_0(int TsPackage_len,TS_Package_Head TS_PackageEITHead)
{
    TS_EIT TS_PackageEIT = {0};
	unsigned char EITtable[204] = {0};

    memcpy(EITtable, TSdata+4, TsPackage_len-4);

	if(eit_n == 0 && CountEIT+1 == TS_PackageEITHead.continuity_counter)
	{
		memcpy(EIT_Long_Table+183, EITtable, TsPackage_len-4);
		CountEIT++;
		eit_n++;
	}else if(CountEIT+1 == TS_PackageEITHead.continuity_counter)
	{
		memcpy(EIT_Long_Table+(183+(184*eit_n)), EITtable, TsPackage_len-4);
		CountEIT++;
		eit_n++;
	}

	if((eit_l / 188) == eit_n)
	{
		TS_EIT *NewEITPoint = (TS_EIT *)malloc(sizeof(TS_EIT));
		TSEIT_Table(EIT_Long_Table, NewEITPoint);
		eit_n = 0;
		memset(EIT_Long_Table, 0, 1200);
	}
}